1. Field of the Invention
The present invention relates to a character string processing method, processing system and program using software object components.
2. Description of the Related Art
Component-based programs (objects) written in an object-oriented programming language are re-usable software objects that run on a particular operating system. Using objects makes it easier to develop a variety of systems and applications. The Component Object Model (COM) supported by the Microsoft Windows® operating system, for example, is a functionally rich system providing an environment in which client applications (container applications) can use and share objects.
By developing systems based on COM objects, software products can be provided as reusable parts enabling individual users to build customized systems and reduce maintenance costs. This design model also enables the further development and evolution of existing software assets, making system development easier and reducing related development costs. The ability to develop objects on a component basis also simplifies developing a complex system consisting of various subsystems or various peripheral devices, and has become essential to the development of systems operating under a network environment.
A POS (Point-Of-Sale) system is one type of system that can be assembled from a variety of peripheral devices. A typical POS system comprises a display device, a printer, scanner, cash drawer, card reader, and other input/output devices, each connected to a personal computer or other central host computer. A flexible personal computer-based POS system built using objects is described in Japanese Patent Laid-Open Publications (kokai) H9-106355 and H9-73395.
Referring to FIG. 1 of this application, the concept of a distributed object POS system 10 is illustrated. This POS system 10 comprises a POS application program 11 supplied by the system manufacturer; a set of control objects (CO) 12, each for a particular type of device (device class), such as a printer 21, a scanner 22, a cash drawer 23, or other type of peripheral device; and a set of service objects 13 (SO), each for a particular device. To print from the POS application program 11, data is first sent to the printer control object, then to the service object for the particular make or model of the printer from which data will be printed, then to the operating system (OS) 14, and finally to the printer 21.
POS system 10 also typically includes other peripheral devices, such as a display 15, a keyboard 16, and other hardware resources of the personal computer. POS application 11 interacts with each of these other peripheral devices and hardware resources via the OS 14.
The object control system 19 containing the set of control objects 12 and set of service objects 13 provides the POS application program 11 with an interface that is independent of any particular peripheral device (such as the printer 21). Because the control objects in set 12 are each developed for a particular device class, a control object instance is created by the COM supported by the OS 14 when the POS application program 11 is run, and the control object instance is bound to the POS application program 11. Each service object in set 13 provides a uniform interface, independent of a particular device, for the corresponding control object in set 12; when a particular device is called by a control object, a service object instance is created and bound to the POS application program 11.
In a COM-based system, for example, ActiveX controls (OLE controls) that can return events to the program 11 can be used for a control object, and an ActiveX server (OLE automation server) operating as a server for ActiveX controls can be used as a service object. The COM provides support for data communications between objects bound by automation, that is, between instances of objects bound in order to run the application program. “Automation server” is a software object containing both properties and methods, and “automation” is a mechanism for publishing or manipulating objects.
Automation is dependent upon the COM IDispatch interface, and communication between objects is accomplished by running the Invoke method. IDispatch is an interface for publishing ActiveX controls and ActiveX server methods and properties for use by a COM-compatible programming language. The Microsoft Foundation Class Library (MFC), which provides a developing environment with an automation function based on Visual C++, an object-oriented programming language published by Microsoft, provides the COleDispatchDriver base class (object) for handling the complexities of calling the Invoke function from the application program or client object. A client object can therefore send data to a server object by calling InvokeHelper, a member function of the interface object derived from this base class. In other words, a specific process must be run in order to use the Invoke function, and an InvokeHelper function containing this predefined process is provided to help call the Invoke function. This predefined process includes, for example, reading arguments from a list and running a process based on these arguments, converting the Invoke result to a method, or throwing exceptions when an illegal process is run.
FIG. 2 schematically shows the flow of data from a POS application program 11 to a device (e.g., printer 21). In order to print text data on the printer 21, the POS application program 11 calls the print method of the printer control object in set 12 and passes the text data to the print method. In order to call the method of the service object in set 13 for the printer 21, the printer control object calls the InvokeHelper member function of the COleDispatchDriver class (the interface object (IFO) 18). The data is then passed through the interface object 18 to the printer service object in set 13, and through the OS 14 to the printer 21.
One problem is that if a null character (0x00 in hexadecimal; all character data noted below is also in hexadecimal), such as is sometimes contained in bar code data, is present in the text data (character string), the character string will not be reproduced on the printer 21 of the POS system 10. The printer control object in a POS system typically has a PrintBarCode method, and if a data string containing a null (0x00 ) character is specified in the data parameter of the PrintBarCode method, the data string is passed by a process such as follows.
First, the POS application program 11 sends the following character string A0 to the control object.
A0: 7B 41 00 30 31 32 33 34 35 36 37 38 39
The control object receives character string A0 declared as a LPCTSTR type. An LPCTSTR is a pointer to a null-terminated (0x00 ) 8-bit ANSI (American National Standard Institute) string, as well as a character string of Shift JIS (Japanese Industrial Standard)-defined characters. A null (0x00 ) character is therefore not allowed in the middle of the string. When not trying to print byte data as image data, null (0x00 ) data is not contained in the printable characters, and character string data is generally declared as a LPCTSTR type in the printer control object.
In a COM environment, however, COM supports application-object and object-object data transfers with character strings passed through COM as BSTR strings, that is, basic or binary strings containing a string length (character count) declaration. String A0 is thus converted to A1.
A1: 0D 00 00 00 7B 4100 30 3132 33 34 35 36 37 38 39 00
A BSTR string thus starts with the string length written to the first four bytes, and ends with 00 (which is not included in the string length (character count)). Note, however, that this 00 is not used as the terminating character. Data memory is managed based on the number of characters from the pointer so that even a null (0x00 ) character contained in the character string is treated as character data.
In order for the printer control object to call the print output method of the printer service object, the printer control object first calls the InvokeHelper member function of the COleDispatchDriver class (interface object 18 provided as an MFC library), and InvokeHelper calls InvokeHelperV as follows:
void COleDispatchDriver::InvokeHelperV(DISPID dwDispID, WORD wFlags, VARTYPE vtRet, Void* pvRet, const BYTE* pbParamInfo, va_list argList), where the parameters are defined as follows:
 dwDispID: Identifies the method or property to be invoked; wFlags: Flags describing the context of the call to IDispatch::Invoke; vtRet: Specifies the type of the return value; pvRet: Address of the variable that will receive the property value or return value; pbParamInfo: Pointer to a null-terminated string of bytes specifying thetypes of the parameters stored in the argList following pbParamInfo; and argList: list of parameters.
COleDispatchDriver::InvokeHelperV thus converts a character string as follows:
LPCSTR lpsz = va_arg(argList, LPSTR);pArg->bstrVal=::SysAllocString(T2COLE(lpsz));if (lpsz != NULL && pArg->bstrVal == NULL) AfxThrowMemoryException();pArg->vt = VT_BSTR;
Because the character string lpsz passed from the control object is declared by an 8-bit Shift JIS as an LPCTSTR, the character conversion macro T2COLE is automatically selected and the characters are converted to 16-bit wide characters (Unicode), the basic transfer string type passed by COM. T2COLE is defined as a model library (ATL: Active Template Library) for creating ActiveX controls using Visual C++.
The first line above directs the reading of the data parameters from the parameter list, and the data is then actually converted by the next line. The character conversion macro T2COLE invokes the AfxA2Whelper function wherein MultiByteToWideChar converts the data to wide characters as shown below.
A2: 7B 00 41 00 00 00
That is, because the control object declares the character string a null-terminated LPCTSTR type, the null (0x00 ) characters contained in the middle of the character string are interpreted as terminating the character string. The result is a character string of a wide character (LPCTSTR) type not containing any data following 00 and deleting everything after 00. The character string is then converted by SysAllocString to a BSTR type containing data about the number of characters (actually bytes) in the string, which is passed through COM to the service object.
The data passed to the service object after the four string length bytes are added is thus:
A3: 04 00 00 00 7B 00 41 00 00 00
Like the control object, the service object also uses LPCTSTR to declare character data, and receives data in 8-bit units according to the declared character string data type by COM. The service object thus receives:
A4: 7B 41 00
The printer 21 controlled by the printer service object is thus unable to print the data specified by the application program 11, and only prints part of the specified data (that is, the received data, A4). While the string data sent by COM is BSTR type and character string A4 can be cast and processed as a BSTR type, the data in memory only contains the string length information of the BSTR type as shown below, and the data omitted when transferred from the control object is lost.
A5: 02 00 00 00 7B 41 00
Thus, if the control object receives string data declared as a LPCTSTR type containing a null (0x00 ) character from the POS application program 11, this string data cannot be sent to the service object and properly output on the printer 21.
Furthermore, changing the declared string data type in the control object or service object cannot be employed in an object-oriented POS system desiring to provide a uniform interface to the application program and unify the parameters exchanged between objects and between the application program and objects. It is also not desirable from the perspective of protecting the current software assets of the user.
There are methods for forcibly converting null (0x00 ) data using binary conversion to some other value before data transfer, and then restoring null (0x00 ) data in a following object. In addition to being complicated, however, the conversion processes used by the different objects must match, and the receiving object is therefore dependent upon the design (operation) of the sending object. This is contradictory to one goal of object-oriented programming, which is to improve software reusability and modularity. Furthermore, if the receiving object cannot process the binary converted data, it might output a completely different character string.
Processing character string data containing null (0x00 ) data thus presents some difficult problems. In order to build a POS system capable of handling bar codes and other different data types, however, it is necessary to be able to accurately send character data containing null (0x00 ) data to the service objects for output by a printer or other device.